﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using EnvDTE80;

namespace CodeJumper
{
    public class ElementLabel : Button
    {
        private readonly CodeElementAggregate _aggregate;
        private readonly ApplicationConfiguration _appConfig;
        private readonly Label _hyperLabel;
        private readonly StackPanel _hyperlinkedStackPanel = new StackPanel();
        private readonly StackPanel _nonHyperlinkedStackpanel = new StackPanel();
        private readonly Button _underlayButton;
        private readonly StackPanel _unifyingStackPanel = new StackPanel();
        private Canvas _pictureGrid;


        public ElementLabel(ApplicationConfiguration appConfig, CodeElementAggregate aggregate)
        {
            _appConfig = appConfig;
            _aggregate = aggregate;

            var menuItem = new MenuItem {Header = "Refactor: Rename"};
            menuItem.Click += (s, e) => DoRename();

            var contextMenu = new ContextMenu();
            contextMenu.Items.Add(menuItem);
            ContextMenu = contextMenu;

            var zeroThick = new Thickness(0);
            CreateAddPictureCanvas();
            _hyperlinkedStackPanel.Orientation = Orientation.Horizontal;
            _nonHyperlinkedStackpanel.Orientation = Orientation.Horizontal;
            _unifyingStackPanel.Orientation = Orientation.Horizontal;
            _nonHyperlinkedStackpanel.Margin = zeroThick;
            _unifyingStackPanel.Margin = zeroThick;

            _underlayButton = new Button {Style = appConfig.EasyButtonStyle, Content = _hyperlinkedStackPanel, Width = 1000};

            _hyperLabel = new Label {Content = _underlayButton, Padding = zeroThick, Margin = zeroThick, VerticalContentAlignment = VerticalAlignment.Center};

            _unifyingStackPanel.Children.Add(_nonHyperlinkedStackpanel);
            _unifyingStackPanel.Children.Add(_hyperLabel);

            Style = appConfig.EasyButtonStyle;
            HorizontalContentAlignment = HorizontalAlignment.Left;
            MouseEnter += (s, e) => { _unifyingStackPanel.Background = appConfig.MouseOverMemberBackgroundBrush; };
            MouseLeave += (s, e) => { _unifyingStackPanel.Background = Brushes.Transparent; };
            Content = _unifyingStackPanel;
            Padding = appConfig.HyperlinkPadding;
            FontSize = appConfig.HyperlinkFontSize;
        }

        private void DoRename()
        {
            var box = new TextBox {Text = _aggregate.Original.Name, Width = 400};
            box.SelectionStart = box.Text.Length;
            box.Focusable = true;

            _hyperLabel.Content = box;
            box.LostFocus += (s, e) => ResetRename();
            box.KeyDown += (s, e) =>
                {
                    if (e.Key == Key.Escape)
                    {
                        ResetRename();
                    }
                    if (e.Key == Key.Enter)
                    {
                        RenameSymbol(box.Text);
                    }
                };
            Dispatcher.BeginInvoke(DispatcherPriority.Loaded, (Action) (() =>
                {
                    box.Focus();
                    Keyboard.Focus(box);
                }));
        }

        private void RenameSymbol(string newname)
        {
            try
            {
                if (newname != _aggregate.Original.Name)
                {
                    var ce2 = _aggregate.Original as CodeElement2;
                    ce2.RenameSymbol(newname);
                }
                ResetRename();
            }
            catch (Exception)
            {
                MessageBox.Show("Refactoring failed.");
            }
        }

        private void ResetRename()
        {
            _hyperLabel.Content = _underlayButton;
        }

        public void Clear()
        {
            _hyperlinkedStackPanel.Children.Clear();
            CreateAddPictureCanvas();
            _nonHyperlinkedStackpanel.Children.Clear();
        }

        private void CreateAddPictureCanvas()
        {
            _pictureGrid = new Canvas {Width = 16, Height = 16};
            _hyperlinkedStackPanel.Children.Add(_pictureGrid);
        }

        public void AddText(string text, Brush brush)
        {
            var block = new TextBlock {Foreground = brush, Text = text, Padding = _appConfig.HyperlinkPadding, FontFamily = _appConfig.AddinFont.FontFamily, FontSize = _appConfig.AddinFont.FontSize};
            _hyperlinkedStackPanel.Children.Add(block);
        }

        public void AddText(string text, Brush brush, Thickness Padding, FontWeight fontWeight)
        {
            var block = new TextBlock {Foreground = brush, Text = text, Padding = Padding, FontWeight = fontWeight, FontFamily = _appConfig.AddinFont.FontFamily, FontSize = _appConfig.AddinFont.FontSize};
            _hyperlinkedStackPanel.Children.Add(block);
        }

        public Image AddPictureToSingleGrid(BitmapImage bi)
        {
            if (bi == null)
                return null;
            var img = new Image {Source = bi, Width = bi.PixelWidth, Height = bi.PixelHeight, Stretch = Stretch.Fill};

            _pictureGrid.Children.Add(img);

            return img;
        }

        public void AddExpander(ElementStackPanel panel, bool isExpanded = true)
        {
            var expander = new Expander {Style = _appConfig.ExpanderStyle, Margin = new Thickness(0, 2, 0, 0)};
            _nonHyperlinkedStackpanel.Children.Add(expander);
            panel.SetExpander(expander);
            expander.Collapsed += (s, e) => panel.Collapse();
            expander.Expanded += (s, e) => panel.Expand();
            expander.IsExpanded = isExpanded;
            if (isExpanded == false)
            {
                panel.Collapse();
            }
        }
    }
}